﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;


public partial class UiCodeCreate
{

    public static readonly UiCodeCreate Instance = new UiCodeCreate();

   
    //private static string prefabDirectory = "/Prefabs";
    private static string prefabExtension = ".prefab";

    
    static void CreateNew(GameObject obj, string localPath)
    {
        
        
        Debug.Log("开始构建预制体");
        PrefabUtility.SaveAsPrefabAssetAndConnect(obj,localPath,InteractionMode.UserAction);
        EditorUtility.DisplayDialog("提示！",
                            "自动构建预制体完成！注意请不要标准化UIPanleType文本，否则将无法自动删除对应枚举",
                            "是");
    }


    [MenuItem("Tools/CreateFolder #&_q")]
    private static void GenerateFolder()
    {
        string prjPath = Application.dataPath + "/";
        Directory.CreateDirectory(prjPath + "Audio");
        Directory.CreateDirectory(prjPath + "Prefabs");
        Directory.CreateDirectory(prjPath + "Materials");
        Directory.CreateDirectory(prjPath + "Resources");
        Directory.CreateDirectory(prjPath + "Scripts");
        Directory.CreateDirectory(prjPath + "Textures");
        Directory.CreateDirectory(prjPath + "Scenes");
        Directory.CreateDirectory(prjPath + "Animation");
        Directory.CreateDirectory(prjPath + "AnimationController");
        Directory.CreateDirectory(prjPath + "Plugins");
        Directory.CreateDirectory(prjPath + "Plugins/iOS");
        Directory.CreateDirectory(prjPath + "Plugins/Android");
        Directory.CreateDirectory(prjPath + "Editor");
        Directory.CreateDirectory(prjPath + "Particle");
        Directory.CreateDirectory(prjPath + "Meshes");
        Directory.CreateDirectory(prjPath + "Shaders");
        Directory.CreateDirectory(Application.streamingAssetsPath);
        AssetDatabase.Refresh();//刷新unity资源显示
        Debug.Log("Created Finished");
    }

   
   
    [MenuItem("GameObject/AutoCreateScript", false, 0)]
    public static void AutoCreateScriptOnHierarchy()
    {

        //获取选中的游戏物体
        GameObject obj = Selection.activeGameObject;
        if (obj == null) return;
        if(obj.name.Contains("Form") && obj.name.Length > 5)

        {
            var tempName = obj.name.GetFrontStr(4);
            //检测目录下是否存在该脚本 如果不存在开始创建
            if (!Instance.GetFileSuccess(Instance._UiFilePath + "Form/" + obj.name + ".cs"))
            {

                EditorPrefs.SetString(GameObjectName, obj.name);
                EditorPrefs.SetString(PanelScriptName, obj.name);

                EditorPrefs.SetString(RequestScriptName, tempName + "Request");

                EditorPrefs.SetString(GameObjectName, obj.name);
                //for (var i = 0; i < objs.Length; i++)
                //{
                Instance.CreatePanelCode(obj as GameObject);
                //}
            }
            else
            {

                if (EditorUtility.DisplayDialog("确定重构吗?",
                    "该脚本已经存在. 你是否想重新构建它?",
                    "是",
                    "否"))
                {
                    Debug.LogWarning("开始备份并重新创建");
                    StringBuilder fileContent = new StringBuilder();
                    fileContent.Append(Instance.GetFileContent(Instance._UiFilePath + "Form/" + obj.name + ".cs"));
                    fileContent = fileContent.Replace(obj.name, tempName + "Form_Backup");
                    Instance.CreateFileAndWrite(tempName + "Form_Backup", fileContent.ToString(), "Backup/" + tempName + "Backup");
                    //检测是否存在Request脚本
                    if (Instance.GetFileSuccess(Instance._UiFilePath + "Request/" + tempName + "Request" + ".cs"))
                    {
                        fileContent.Clear();
                        fileContent.Append(Instance.GetFileContent(Instance._UiFilePath + "Request/" + tempName + "Request" + ".cs"));
                        fileContent = fileContent.Replace(tempName + "Request", tempName + "Request_Backup");
                        Instance.CreateFileAndWrite(tempName + "Request_Backup", fileContent.ToString(), "Backup/" + tempName + "Backup");
                    }
                    Instance.CreatePanelCode(obj as GameObject, tempName);
                }

            }


        }
        else
        {
            EditorUtility.DisplayDialog("提示！",
                         "所选对象必须为Form，命名为xxxForm",
                         "是");
        }


        AssetDatabase.Refresh();


    }

    [MenuItem("GameObject/AutoDeleteScript", false, 0)]
    public static void AutoDeleteScriptOnHierarchy()
    {
        //获取选中的Prefab
        if (EditorUtility.DisplayDialog("提示！",
                         "是否要删除自动生成的所有文件？该操作可能会出现未知错误",
                         "是", "否"))
        {
            //获取选中的游戏物体
            GameObject obj = Selection.activeGameObject;
            if (obj!=null)
            {
                if (obj.name.Contains("Form"))
                {
                    var panelPath = "Assets/GameMain/Scripts/UI/Form" + "/";  //panel路径
                    var requestlPath = "Assets/GameMain/Scripts/Request" + "/";  //request路径
                    var backuplPath = "Assets/GameMain/Scripts/UI/Backup" + "/";  //baskUp 备份路径
                    var resoursPath = "Assets/GameMain/UIForm" + "/";  //prefab路径
                    var objname = obj.name.GetFrontStr(4);
                    //PrefabUtility.UnpackPrefabInstance((GameObject)objs[0], PrefabUnpackMode.OutermostRoot, InteractionMode.UserAction);
                    //删除资源目录下的文件
                    if (File.Exists(resoursPath + obj.name + prefabExtension))
                    {
                        File.Delete(resoursPath + obj.name + prefabExtension+".meta");
                        File.Delete(resoursPath + obj.name + prefabExtension);
                    }
                    //删除目录下的备份文件
                    if (Directory.Exists(backuplPath + objname + "Backup"))
                    {
                        foreach (FileInfo file in (new DirectoryInfo(backuplPath + objname + "Backup")).GetFiles())
                        {
                            file.Attributes = FileAttributes.Normal;
                            file.Delete();
                        }

                        Directory.Delete(backuplPath + objname + "Backup");
                    }
                    //删除Panel路径下的文件
                    if (Directory.Exists(panelPath))
                    {
                      
                        if (Instance.GetFileSuccess(panelPath + objname + "Form.cs"))
                        {
                          
                            File.Delete(panelPath + objname + "Form.cs");
                            File.Delete(panelPath + objname + "Form.cs.meta");
                        }
                    }
                    //删除Request路径下的文件
                    if (Directory.Exists(requestlPath))
                    {
                        if (Instance.GetFileSuccess(requestlPath + objname + "Request.cs"))
                        {
                            File.Delete(requestlPath + objname + "Request.cs");
                            File.Delete(requestlPath + objname + "Request.cs.meta");
                        }
                    }
                    GameObject selectObj = (GameObject)obj;
                    //修改所选物体上的所有UIType为false
                    UIType[] allChild = selectObj.GetComponentsInChildren<UIType>(true);
                    foreach (UIType child in allChild)
                    {

                        child.SetBuild(false);
                        child.parentNameList.Clear();

                    }
                    //TODO:自动删除对应的枚举 和 路径
                    //第一步删除枚举文件下的枚举类型
                    Instance.DeleteTypeAndPath(objname);
                  

                }
                else
                {
                    EditorUtility.DisplayDialog("提示！",
                                 "所选对象必须为Panel，命名为xxxPanel",
                                 "是");
                }

               
                AssetDatabase.Refresh();
            }

        }

    }

    /// <summary>
    /// 创建Panel类
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="objPath"></param>
    private void CreatePanelCode(GameObject obj, string fileContentStr = null)
    {


        //变量声明
        StringBuilder statementContent = new StringBuilder();
        //变量绑定
        StringBuilder bindVariableContent = new StringBuilder();

        // 变量绑定方法
        StringBuilder bindMethodContent = new StringBuilder();
        //变量方法
        StringBuilder methodContent = new StringBuilder();
        //写入内容
        StringBuilder fileContent = new StringBuilder();
        // 判断是否存在服务器和客户端共有的Dll 如果有则需要为Panel创建对应的Request
        if (_orHaveDllCommon && fileContentStr == null)
        {

            if (fileContentStr == null)
            {
                CreateRequestCode(obj);
            }
            else
            {
                CreateRequestCode(obj, fileContentStr);

            }
            var requestname = obj.name.GetFrontStr() + "Request";
            statementContent.Append("\n");
            statementContent.Append("	");
            //statementContent.Append("private" + " " + requestname + " " + StringExtension.LowercaseFirst(requestname) + ";");
            statementContent.Append("private" + " " + requestname + " " + requestname.LowercaseFirst() + ";");
            bindVariableContent.Append("\n");
            bindVariableContent.Append("		");
            //bindVariableContent.Append(StringExtension.LowercaseFirst(requestname) + "=GetComponent<" + requestname + ">();");
            bindVariableContent.Append(requestname.LowercaseFirst() + "=GetComponent<" + requestname + ">();");
        }

        if (fileContentStr == null)
        {
            fileContent.Append(_panelTemplateContent);
        }
        else
        {

            fileContent.Append(Instance.GetFileContent(Instance._UiFilePath + "Backup/" + fileContentStr + "Backup/" + fileContentStr + "Form_Backup.cs"));
        }

        foreach (UIType child in obj.GetComponentsInChildren<UIType>(true))
        {
            if (child.parentNameList.Count == 0)
            {
                child.GetGameobjectPath(child.gameObject);
            }
            
            if (!child.OrBuild)
            {
                statementContent.Append("\n");
                statementContent.Append("	");
                statementContent.Append(child.StatementContent);
                bindVariableContent.Append("\n");
                bindVariableContent.Append("		");
                bindVariableContent.Append(child.BindVariableContent);
                bindMethodContent.Append("\n");
                bindMethodContent.Append("		");
                bindMethodContent.Append(child.BindMethodContent);
                methodContent.Append("\n");
                methodContent.Append("	");
                methodContent.Append(child.MethodContent);
                
            }
            child.SetBuild();

        }
        //替换脚本名和命名空间
        //fileContent = fileContent.Replace("TemNamespace", "UI."+obj.name).Replace("ViewTemplate", obj.name);
        if (fileContentStr == null)
        {
            fileContent = fileContent.Replace("PanelTemplate", obj.name);
        }
        else
        {
            fileContent = fileContent.Replace(obj.name + "_Backup", obj.name);
        }

        //添加属性和绑定
        fileContent = fileContent.Replace("/*声明*/", "/*声明*/" + statementContent.ToString()).Replace("/*绑定*/", "/*绑定*/" + bindVariableContent.ToString()).Replace("/*绑定方法*/", "/*绑定方法*/" + bindMethodContent.ToString()).Replace("/*方法*/", "/*方法*/" + methodContent.ToString());
        CreateFileAndWrite(obj.name, fileContent.ToString(), "Form");
        WriteTypeAndPath(obj.name/*.GetFrontStr()*/);




    }



    /// <summary>
    /// 创建Request类
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="objPath"></param>
    private void CreateRequestCode(GameObject obj, string fileContentStr = null)
    {
        //写入内容
        StringBuilder fileContent = new StringBuilder();
        if (fileContentStr == null)
        {
            fileContent.Append(_requestTemplateContent);
        }
        else
        {
            fileContent.Append(Instance.GetFileContent(Instance._UiFilePath + "Backup/" + fileContentStr + "Backup/" + fileContentStr + "Request_Backup.cs"));
            //fileContent.Append(Instance.GetFileContent(fileContentStr));
        }

        //替换脚本名和命名空间
        //fileContent = fileContent.Replace("TemNamespace", "UI."+obj.name).Replace("RequestTemplate", obj.name);
        var objnewname = obj.name.GetFrontStr();
        if (fileContentStr == null)
        {
            fileContent = fileContent.Replace("RequestTemplate", objnewname + "Request");
        }
        else
        {

            fileContent = fileContent.Replace(objnewname + "Request_Backup", objnewname + "Request");
        }

        fileContent = fileContent.Replace("None", objnewname);
        CreateFileAndWrite(objnewname + "Request", fileContent.ToString(), "Request");
    }

    /// <summary>
    /// 将创建的Prefab的路径和名称写入对应的Json文件和路径中
    /// </summary>
    /// <param name="writeName"></param>
    private void WriteTypeAndPath(string writeName)
    {
        //判断是否存在类型文件 如果存在读取文件内容并添加写入 类型枚举中
        if (GetFileSuccess(_typeForPanelPath))
        {

            //写入内容
            StringBuilder fileContent = new StringBuilder();
            fileContent.Append(GetFileContent(_typeForPanelPath));

            if (!fileContent.ToString().Contains(writeName))
            {
                fileContent = fileContent.Replace("/*枚举类型*/", ",\n\t\t" + writeName + "/*枚举类型*/");
                CreateFileAndWrite(_typeForPanelPath, fileContent.ToString());
            }



        }
        else
        {
            Debug.Log("Type不存在");
        }

        if (GetFileSuccess(_jsonForPanelPath))
        {

            //写入内容
            StringBuilder fileContent = new StringBuilder();
            fileContent.Append(GetFileContent(_jsonForPanelPath));

            var temp = ",\n\t\n\t    {\"" + "panelTypeString" + "\":" + "\"" + writeName + "\",\n\t" + "\"" + "path" + "\":" + "\"UIPanel/" + writeName + "Panel" + "\"}";

            if (!fileContent.ToString().Contains(writeName))
            {
                fileContent = fileContent.Replace("/**/", temp + "/**/");

                CreateFileAndWrite(_jsonForPanelPath, fileContent.ToString());
            }


        }
        else
        {
            Debug.Log("Json不存在");
        }
    }
    /// <summary>
    /// 将创建的Prefab的路径和名称从对应的Json文件和路径中删除
    /// </summary>
    /// <param name="writeName"></param>
    private void DeleteTypeAndPath(string writeName)
    {
        //判断是否存在类型文件 如果存在读取文件内容并添加写入 类型枚举中
        if (GetFileSuccess(_typeForPanelPath))
        {

            //删除内容
            StringBuilder fileContent = new StringBuilder();
            fileContent.Append(GetFileContent(_typeForPanelPath));

            if (fileContent.ToString().Contains(writeName))
            {
                fileContent = fileContent.Replace(",\n\t" + writeName, "");
                CreateFileAndWrite(_typeForPanelPath, fileContent.ToString());
            }
            else
            {
                Debug.Log("不存在"+ ",\n\t" + writeName);
               
            }


        }
        else
        {
            Debug.Log("Type不存在");
        }

        if (GetFileSuccess(_jsonForPanelPath))
        {

            //写入内容
            StringBuilder fileContent = new StringBuilder();
            fileContent.Append(GetFileContent(_jsonForPanelPath));

            var temp = ",\n\t\n\t    {\"" + "panelTypeString" + "\":" + "\"" + writeName + "\",\n\t" + "\"" + "path" + "\":" + "\"UIPanel/" + writeName + "Panel" + "\"}";

            if (fileContent.ToString().Contains(temp))
            {
                fileContent = fileContent.Replace(temp, "");

                CreateFileAndWrite(_jsonForPanelPath, fileContent.ToString());
            }


        }
        else
        {
            Debug.Log("Json不存在");
        }
    }

    /// <summary>
    /// 获取文件内容
    /// </summary>
    /// <param name="filePath"></param>
    /// <returns></returns>
    private string GetFileContent(string filePath)
    {
        if (File.Exists(filePath))
        {
            return File.ReadAllText(filePath);

        }
        else
        {
            Debug.Log("Error:[" + filePath + "]该文件不存在！");
            return null;
        }
    }

    /// <summary>
    /// 获取文件是否存在
    /// </summary>
    /// <param name="filePath"></param>
    /// <returns></returns>
    private bool GetFileSuccess(string filePath)
    {
        if (File.Exists(filePath))
        {
            return true;

        }
        else
        {

            return false;
        }
    }

    /// <summary>
    /// 创建文件并写入
    /// </summary>
    /// <returns></returns>
    private void CreateFileAndWrite(string name, string content, string type)
    {
        var path = _UiFilePath + type;
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        File.WriteAllText(path + "/" + name + ".cs", content);
    }

    /// <summary>
    /// 创建文件并写入
    /// </summary>
    /// <returns></returns>
    private void CreateFileAndWrite(string name, string content)
    {
        //var path = name;
        //if (!Directory.Exists(path))
        //{
        //    Directory.CreateDirectory(path);
        //}
        File.WriteAllText(name, content);
    }

    [UnityEditor.Callbacks.DidReloadScripts]
    static void AddComponentGameObject()
    {

        

        GameObject[] objectArray = Selection.gameObjects;
        if (objectArray.Length > 0)
        {
            if (objectArray[0].name.Contains("Form") && objectArray[0].name.Length > 5)
            {

                if(EditorPrefs.GetString(PanelScriptName)!= "PanelScriptName")
                {

                    //添加脚本
                    if (Instance._orHaveDllCommon)
                    {
                        _ScriptNameList.Add(EditorPrefs.GetString(RequestScriptName));
                        PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Android, "INTERNET_GAME;NEW_UI");
                        PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.iOS, "INTERNET_GAME;NEW_UI");
                        PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, "INTERNET_GAME;NEW_UI");
                    }
                    _ScriptNameList.Add(EditorPrefs.GetString(PanelScriptName));
                    for (int i = 0; i < _ScriptNameList.Count; i++)
                    {
                        string className = _ScriptNameList[i];
                        if (string.IsNullOrEmpty(className))
                        {
                            return;
                        }

                        var assemblies = AppDomain.CurrentDomain.GetAssemblies();

                        var defaultAssembly = assemblies.First(assembly => assembly.GetName().Name == "Assembly-CSharp");

                        var typeName = className;


                        var type = defaultAssembly.GetType(typeName);

                        if (type == null)
                        {
                            Debug.Log("编译失败" + typeName);
                            return;
                        }

                        Debug.Log(type);

                        var gameObject = GameObject.Find(EditorPrefs.GetString(GameObjectName));

                        var scriptComponent = gameObject.GetComponent(type);

                        if (!scriptComponent)
                        {
                            scriptComponent = gameObject.AddComponent(type);
                        }


                    }
                    EditorPrefs.DeleteKey(PanelScriptName);
                    EditorPrefs.DeleteKey(RequestScriptName);
                    EditorPrefs.DeleteKey(GameObjectName);
                    Debug.Log("开始自动添加预制体");
                    //添加预制体
                    foreach (GameObject gameObject in objectArray)
                    {
                        //Set the path as within the Assets folder, and name it as the GameObject's name with the .prefab format
                        string localPath = "Assets/GameMain/UIForm/" + gameObject.name + ".prefab";

                        if (!Directory.Exists("Assets/GameMain/UIForm/"))
                        {
                            Directory.CreateDirectory("Assets/GameMain/UIForm/");
                        }
                        //Check if the Prefab and/or name already exists at the path
                        if (AssetDatabase.LoadAssetAtPath(localPath, typeof(GameObject)))
                        {
                            //Create dialog to ask if User is sure they want to overwrite existing Prefab
                            if (EditorUtility.DisplayDialog("确定重构吗?",
                                "该预制体已经存在. 你是否想重新构建它?",
                                "是",
                                "否"))
                            //If the user presses the yes button, create the Prefab
                            {
                                localPath = AssetDatabase.GenerateUniqueAssetPath(localPath);
                                Debug.Log(gameObject.name + "---" + localPath);
                                CreateNew(gameObject, localPath);
                            }
                        }
                        //If the name doesn't exist, create the new Prefab
                        else
                        {

                            localPath = AssetDatabase.GenerateUniqueAssetPath(localPath);
                            Debug.Log(localPath);
                            CreateNew(gameObject, localPath);
                        }
                    }

                }



            }

        }

    }


}
